package com.ruoyi.system.service.impl;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.system.domain.ClassificationNode;
import com.ruoyi.system.domain.dto.GetAttrResponse;
import com.ruoyi.system.domain.dto.GetNodeResponse;
import com.ruoyi.system.domain.dto.NodeInfoResponse;
import com.ruoyi.system.service.ISysClassificationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;


import java.net.URI;
import java.util.*;

@Service
@Slf4j
public class SysClassificationService implements ISysClassificationService {

    @Value("${miniBom.commonNodeUrl}")
    private String commonNodeUrl;

    @Value("${miniBom.basicNodeUrl}")
    private String basicNodeUrl;

    @Value("${miniBom.auth_token}")
    private String token;
    @Autowired
    private RestTemplate restTemplate;


    private HttpHeaders createHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.set("X-Auth-Token", token);

        return headers;
    }


    public Map<String,String> getNode(String parentId) {
        log.info("Entering getNode method");
        log.info("parentId:",parentId);
        // 构建API请求头
        HttpHeaders headers = createHeaders();

        if ("0".equals(parentId)) {
            log.info("parent : root");
            // Create the request body
            Map<String, Object> requestBody = new HashMap<>();
            Map<String, Object> params = new HashMap<>();

            String nodeurl = commonNodeUrl + "/find";
            // Build sorts
            List<Map<String, String>> sorts = new ArrayList<>();
            Map<String, String> sort1 = new HashMap<>();
            sort1.put("sort", "ASC");
            sort1.put("orderBy", "nameEn");
            sorts.add(sort1);

            Map<String, String> sort2 = new HashMap<>();
            sort2.put("sort", "ASC");
            sort2.put("orderBy", "businessCode");
            sorts.add(sort2);

            // Build filter conditions
            List<Map<String, Object>> conditions = new ArrayList<>();
            Map<String, Object> condition1 = new HashMap<>();
            condition1.put("conditionName", "parentNode.id");
            condition1.put("operator", "ISNULL");
            conditions.add(condition1);

            Map<String, Object> condition2 = new HashMap<>();
            condition2.put("conditionName", "rdmDeleteFlag");
            condition2.put("operator", "=");
            condition2.put("conditionValues", Collections.singletonList("0"));
            conditions.add(condition2);

            // Build filter
            Map<String, Object> filter = new HashMap<>();
            filter.put("joiner", "and");
            filter.put("conditions", conditions);

            // Put all params together
            params.put("sorts", sorts);
            params.put("filter", filter);
            params.put("isNeedTotal", true);

            requestBody.put("params", params);


            //创建http请求实体
            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody,headers);

            ResponseEntity<Map> response = restTemplate.postForEntity(
                    nodeurl,
                    request,
                    Map.class
            );

            Map<String,String> answer = extractAnswerFromResponse(response.getBody());
            return answer;
        }
//        parentId不为0，查询该父节点下的所有子节点
        else{
            log.info("parent : ",parentId);

            String nodeurl=basicNodeUrl+"/getChildren";

            String url = UriComponentsBuilder.fromHttpUrl(nodeurl)
                    .queryParam("parentId", parentId) // 添加查询参数
                    .toUriString();

            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(headers);

            ResponseEntity<Map> response = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    requestEntity,
                    Map.class
            );
            Map<String,String> answer = extractAnswerFromResponse(response.getBody());
            return answer;
        }

    }

    public boolean haveChild(String parentId){

        log.info("entering haveChild method");

        HttpHeaders headers = createHeaders();

        String nodeurl=basicNodeUrl+"/getChildren";
        String url = UriComponentsBuilder.fromHttpUrl(nodeurl)
                .queryParam("parentId", parentId) // 添加查询参数
                .toUriString();

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<Map> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                requestEntity,
                Map.class
        );

        List<Map> dataList = (List<Map>) response.getBody().get("data");
        if(response.getBody().get("result").equals("SUCCESS") && dataList!=null && dataList.size()!=0){
            return true;
        }
        else{
            return false;
        }


    }

    public Map<String,String> getNodeInformation(String id){

        log.info("entering getNodeInformation method");
        // 构建API请求头
        HttpHeaders headers = createHeaders();
        String nodeurl=commonNodeUrl+"/get";

        Map<String, Object> requestBody = new HashMap<>();
        Map<String, Object> params = new HashMap<>();

        params.put("id",id);
        requestBody.put("params",params);

        //创建http请求实体
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        ResponseEntity<Map> response = restTemplate.postForEntity(
                nodeurl,
                request,
                Map.class
        );

        Map<String,String> answer = extractNodeInformationFromResponse(response.getBody());
        return answer;

    }
    public Map<String,String> getAttribute(String id,int pageSize,int curPage){

        log.info("entering getAttribute method");

        // 构建API请求头
        HttpHeaders headers = createHeaders();
        String attrurl=basicNodeUrl+"/attribute/find/"+pageSize+"/"+curPage;

        Map<String, Object> requestBody = new HashMap<>();
        Map<String, Object> params = new HashMap<>();

        // 1. 添加排序参数
        params.put("sort", "DESC");
        params.put("orderBy", "lastUpdateTime");

        // 2. 构建过滤条件
        Map<String, Object> filter = new HashMap<>();
        filter.put("joiner", "and");

        List<Map<String, Object>> conditions = new ArrayList<>();

        // 条件1: linkId = ""
        Map<String, Object> condition1 = new HashMap<>();
        condition1.put("conditionName", "linkId");
        condition1.put("operator", "=");
        condition1.put("conditionValues", Collections.singletonList(id));
        conditions.add(condition1);

        // 条件2: type != "CATEGORY"
        Map<String, Object> condition2 = new HashMap<>();
        condition2.put("conditionName", "type");
        condition2.put("operator", "<>");
        condition2.put("conditionValues", Collections.singletonList("CATEGORY"));
        conditions.add(condition2);

        filter.put("conditions", conditions);
        params.put("filter", filter);

        // 3. 添加其他参数
        params.put("isNeedTotal", true);

        // 4. 组合最终请求体
        requestBody.put("params", params);


//        log.info(attrurl);
        //创建http请求实体
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        ResponseEntity<Map> response = restTemplate.postForEntity(
                attrurl,
                request,
                Map.class
        );
        Map<String,String> answer = extractAttrFromResponse(response.getBody());
        return answer;


    }

    public Map<String,String> createTypeNode(ClassificationNode createNewNode){

        log.info("entering createTypeNode method");
        // 构建API请求头
        HttpHeaders headers = createHeaders();

        String nodeurl=basicNodeUrl+"/create";

        Map<String, Object> requestBody = new HashMap<>();
        Map<String, Object> params = new HashMap<>();
        params.put("name",createNewNode.getName());
        params.put("nameEn",createNewNode.getNameEn());
        params.put("description",createNewNode.getDescription());

        if(createNewNode.getDescriptionEn() != null){
            params.put("descriptionEn",createNewNode.getDescriptionEn());
        }

        if(!createNewNode.getParentId().equals("0")){
            Map<String, Object> parentNode = new HashMap<>();
            parentNode.put("id",createNewNode.getParentId());
            params.put("parentNode",parentNode);
        }
        requestBody.put("params", params);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        ResponseEntity<Map> response = restTemplate.postForEntity(
                nodeurl,
                request,
                Map.class
        );

        Map<String,String> answer = extractAnswerFromResponse(response.getBody());
        return answer;

    }


    public String addNodeAttr(String id,String[] attrIdArray){

        log.info("entering addNodeAttr method");

        // 构建API请求头
        HttpHeaders headers = createHeaders();
        String attrurl=basicNodeUrl+"/attribute/add";

        Map<String, Object> requestBody = new HashMap<>();
        Map<String, Object> params = new HashMap<>();

        params.put("holderId",id);
        params.put("attrIds",attrIdArray);
        requestBody.put("params",params);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(
                attrurl,
                request,
                String.class
        );

        return response.getBody();

    }

    public String deleteNodeAttr(String[] linkIdArray){

        log.info("entering deleteNodeAttr method");

        // 构建API请求头
        HttpHeaders headers = createHeaders();
        String attrurl=basicNodeUrl+"/attribute/remove";

        Map<String, Object> requestBody = new HashMap<>();
        Map<String, Object> params = new HashMap<>();
        params.put("linkIds",linkIdArray);

        requestBody.put("params",params);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(
                attrurl,
                request,
                String.class
        );
        return response.getBody();


    }
    public String deleteTypeNode(String id){

        log.info("entering deleteTypeNode method");

        // 构建API请求头
        HttpHeaders headers = createHeaders();
        String nodeurl=basicNodeUrl+"/delete";

        Map<String, Object> requestBody = new HashMap<>();
        Map<String, Object> params = new HashMap<>();
        params.put("id",id);
        requestBody.put("params",params);

        try {
            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
            ResponseEntity<Map> response = restTemplate.postForEntity(
                    nodeurl,
                    request,
                    Map.class
            );

            // Map → JSON String
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.writeValueAsString(response.getBody());

        }catch(Exception e) {
            e.printStackTrace();
            return "error in deleteTypeNode";
        }

    }

    public Map<String,String> searchByName(ClassificationNode typeNode){

        log.info("entering searchByName method");

        // 构建API请求头
        HttpHeaders headers = createHeaders();
        String nodeurl=basicNodeUrl+"/getCategoryTreeByName";
        String url = nodeurl;

        if(typeNode.getName()!=null) {
//            log.info("11111111");
            log.info(typeNode.getName());

            url = UriComponentsBuilder.fromHttpUrl(nodeurl)
                    .queryParam("name", typeNode.getName()) // 添加查询参数
                    .toUriString();
//                log.info(url);

        }
        else if(typeNode.getNameEn()!=null){
//            log.info("222222222");

            url = UriComponentsBuilder.fromHttpUrl(nodeurl)
                    .queryParam("nameEn", typeNode.getNameEn()) // 添加查询参数
                    .toUriString();
        }
        else{
//            log.info("3333333333");
            Map<String,String> data = new HashMap<>();

            data.put("result","error in extractAnswerFromResponse");
            data.put("state","FAIL");
            return data;
        }


        //url中的string类型中文编码会存在问题，故此处使用uri类型
        URI requestUri = URI.create(url);
        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(headers);

        ResponseEntity<Map> response = restTemplate.exchange(
                requestUri,
                HttpMethod.GET,
                requestEntity,
                Map.class
        );

        Map<String,String> answer = extractNodeInformationFromResponse(response.getBody());
        return answer;

    }


    public Map<String,String> serchByBusinessCode(String businessCode){

        log.info("entering searchByBusinessCode method");


        // 构建API请求头
        HttpHeaders headers = createHeaders();
        String nodeurl=commonNodeUrl+"/getByBusinessCode";

        Map<String, Object> requestBody = new HashMap<>();
        Map<String, Object> params = new HashMap<>();
        params.put("businessCode",businessCode);
        requestBody.put("params",params);

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        ResponseEntity<Map> response = restTemplate.postForEntity(
                nodeurl,
                request,
                Map.class
        );
        Map<String,String> answer = extractNodeInformationFromResponse(response.getBody());
        return answer;
    }



    //用于获取返回分类node信息，提取出id 和 name
    public Map<String,String> extractAnswerFromResponse(Map responseBody) {
        // 根据API响应格式解析答案
        try {
            log.info("extracting answer from response");
            List<Map> dataList = (List<Map>) responseBody.get("data");
            List<GetNodeResponse> resultList = new ArrayList<>();
            log.info("extracting...........");
            // Extract id and name from each item
            for (Map<String, Object> item : dataList) {
                GetNodeResponse entry = new GetNodeResponse();

                entry.setId(item.get("id").toString());
                entry.setName(item.get("name").toString());

                if(haveChild(item.get("id").toString()))
                    entry.setChildren(true);
                else{
                    entry.setChildren(false);
                }
                resultList.add(entry);
            }
            Map<String,String> data = new HashMap<>();
            ObjectMapper objectMapper = new ObjectMapper();

            data.put("result",objectMapper.writeValueAsString(resultList));
            data.put("state","SUCCESS");
            return data;
        }catch (Exception e) {
            e.printStackTrace();
            Map<String,String> data = new HashMap<>();

            data.put("result","error in extractAnswerFromResponse");
            data.put("state","FAIL");
            return data;
        }
    }

    public Map<String,String> extractNodeInformationFromResponse(Map responseBody){
        // 根据API响应格式解析答案
        try {
            log.info("extracting node information from response");
//            System.out.println("Response Body: " + responseBody);
            List<Map> dataList = (List<Map>) responseBody.get("data");
            List<NodeInfoResponse> resultList = new ArrayList<>();
            // Extract id and name from each item
            for (Map<String, Object> item : dataList) {
                NodeInfoResponse entry = new NodeInfoResponse();
                entry.setId(item.get("id")!=null ? item.get("id").toString() : "");
                entry.setName( item.get("name")!=null ? item.get("name").toString() : "");
                entry.setCreateTime(item.get("createTime")!=null ? item.get("createTime").toString() : "");
                entry.setLastUpdateTime(item.get("lastUpdateTime")!=null ? item.get("lastUpdateTime").toString() : "");
                entry.setBusinessCode(item.get("businessCode")!=null ?item.get("businessCode").toString():"");
                entry.setNameEn(item.get("nameEn")!=null ? item.get("nameEn").toString() : "");
                entry.setDescription(item.get("description")!=null ?item.get("description").toString():"");

                entry.setDescriptionEn(item.get("descriptionEn")!=null ?item.get("descriptionEn").toString():"");

                if(item.get("parentNode")!=null){
                    Map<String, Object> parentNode = (Map<String, Object>) item.get("parentNode");
                    entry.setParentNode(parentNode);
                }
                resultList.add(entry);
            }
            Map<String,String> data = new HashMap<>();
            ObjectMapper objectMapper = new ObjectMapper();


            data.put("result",objectMapper.writeValueAsString(resultList));
            data.put("state","SUCCESS");
            return data;
        }catch (Exception e) {
            e.printStackTrace();
            Map<String,String> data = new HashMap<>();

            data.put("result","error in extractNodeInformationFromResponse");
            data.put("state","FAIL");
            return data;
        }
    }
    public Map<String,String> extractAttrFromResponse(Map responseBody){
        try {
            log.info("extracting attribute from response");
            System.out.println("Response Body: " + responseBody);
            if(!responseBody.get("result").equals("SUCCESS")){

                return responseBody;
            }
            List<Map> dataList = (List<Map>) responseBody.get("data");

            List<GetAttrResponse> resultList = new ArrayList<>();
            for (Map<String, Object> item : dataList) {
                GetAttrResponse entry = new GetAttrResponse();
                entry.setId(item.get("id") != null ? item.get("id").toString() : "");
                entry.setLinkId(item.get("linkId") != null ? item.get("linkId").toString() : "");
                entry.setName(item.get("name") != null ? item.get("name").toString() : "");
                entry.setNameEn(item.get("nameEn") != null ? item.get("nameEn").toString() : "");
                entry.setDescription(item.get("description") != null ? item.get("description").toString() : "");
                entry.setDescriptionEn(item.get("descriptionEn") != null ? item.get("descriptionEn").toString() : "");

                Map<String, Object> constraintMap = (Map<String, Object>) item.get("constraint");
                if (constraintMap != null) {
                    entry.setRange(constraintMap.get("range") != null ? constraintMap.get("range").toString() : "");
                    entry.setNotNull(constraintMap.get("notnull") != null && constraintMap.get("notnull").equals(true)?true : false );
                    entry.setLength(constraintMap.get("length") != null ? constraintMap.get("length").toString() : "");
                } else {
                    entry.setRange("");
                    entry.setNotNull(false);
                    entry.setLength("");
                }

                entry.setDefaultValue(item.get("defaultValue") != null ? item.get("defaultValue").toString() : "");
                entry.setType(item.get("type") != null ? item.get("type").toString() : "");
                resultList.add(entry);
            }
            Map<String,String> data = new HashMap<>();
            ObjectMapper objectMapper = new ObjectMapper();

            data.put("result",objectMapper.writeValueAsString(resultList));
            data.put("state","SUCCESS");
            return data;

        }catch (Exception e) {
            e.printStackTrace();
            Map<String,String> data = new HashMap<>();

            data.put("result","error in extractAttrFromResponse");
            data.put("state","FAIL");
            return data;
        }
    }
}